package s.n.bespin.controller;

import java.lang.reflect.Method;

import s.n.bespin.chain.ChainBuilder.Chain;
import s.n.bespin.container.BespinContainer;
import s.n.bespin.di.annotation.Resource;
import s.n.bespin.exception.BespinException;
import s.n.bespin.io.CommandLineReader;
import s.n.bespin.io.CommandLineWriter;
import s.n.bespin.io.Reader;
import s.n.bespin.io.Writer;

/**
 * @author NAGAI Satoshi
 */
public class CLIController {

	private BespinContainer container;

	@Resource
	private Reader reader;

	@Resource
	private Writer writer;

	public CLIController() {
		container = new BespinContainer();
		reader = new CommandLineReader();
		writer = new CommandLineWriter();
	}

	public void run(Chain chain) {
		try {
			innerRun(chain);
		} catch (Exception e) {
			e.printStackTrace();
			if (e instanceof BespinException) {

			} else {

			}
		}
	}

	private void innerRun(Chain chain) throws Exception {
		String line = null;
		if (chain.message() != null) {
			writer.write(chain.message());
			line = reader.read();
		}
		Chain next = invoke(chain.className(), chain.methodName(), line);
		if (next == null) {
			return;
		}
		innerRun(next);
	}

	private Chain invoke(String className, String methodName, String line)
			throws Exception {
		Class<?> c = Class.forName(className);
		Object o = c.newInstance();
		Method m = c.getMethod(methodName, new Class[] { BespinContainer.class,
				String.class });
		return (Chain) m.invoke(o, new Object[] { container, line });
	}
}
